package com.x.xiaoshuo.service;

import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.hwangjr.rxbus.RxBus;
import com.hwangjr.rxbus.annotation.Subscribe;
import com.hwangjr.rxbus.thread.EventThread;
import com.x.service.api.DataRepository;
import com.x.service.entity.Chapter;
import com.x.service.entity.ChapterList;
import com.x.xiaoshuo.R;
import com.x.xiaoshuo.XApplication;
import com.x.xiaoshuo.di.XAppComponent;
import com.x.xiaoshuo.entity.DownloadMessage;
import com.x.xiaoshuo.entity.DownloadProgress;
import com.x.xiaoshuo.entity.DownloadQueue;
import com.x.xiaoshuo.manager.CacheManager;
import com.x.xiaoshuo.manager.DownloadNotificationManager;
import com.x.xiaoshuo.utils.NetworkUtils;

import java.util.ArrayList;
import java.util.List;

import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;
import timber.log.Timber;

public class DownloadBookService extends Service {

    public class DownloadBinder extends Binder {
        public DownloadBookService getService() {
            return DownloadBookService.this;
        }
    }

    //通过binder实现调用者client与Service之间的通信
    private DownloadBinder binder = new DownloadBinder();

    DownloadNotificationManager downloadNotificationManager;

    public static List<DownloadQueue> downloadQueues = new ArrayList<>();

    public DataRepository bookApi;
    protected CompositeSubscription mCompositeSubscription;

    public boolean isBusy = false; // 当前是否有下载任务在进行

    public static boolean canceled = false;

    @Override
    public void onCreate() {
        super.onCreate();
        RxBus.get().register(this);
        bookApi = ((XAppComponent) XApplication.getInstance().getAppComponent()).getDataRepository();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unSubscribe();
        RxBus.get().unregister(this);
    }

    public static void post(DownloadQueue downloadQueue) {
        RxBus.get().post(downloadQueue);
    }

    public void post(DownloadProgress progress) {
        RxBus.get().post(progress);
    }

    private void post(DownloadMessage message) {
        RxBus.get().post(message);
    }


    @Subscribe(thread = EventThread.MAIN_THREAD)
    public synchronized void addToDownloadQueue(DownloadQueue queue) {
        if (!TextUtils.isEmpty(queue.bookId)) {
            boolean exists = false;
            // 判断当前书籍缓存任务是否存在
            for (int i = 0; i < downloadQueues.size(); i++) {
                if (downloadQueues.get(i).bookId.equals(queue.bookId)) {
                    Timber.e("addToDownloadQueue:exists");
                    exists = true;
                    break;
                }
            }
            if (exists) {
                post(new DownloadMessage(queue.bookId, "当前缓存任务已存在", false));
                return;
            }

            // 添加到下载队列
            downloadQueues.add(queue);
            Timber.e("addToDownloadQueue:" + queue.bookId);
            post(new DownloadMessage(queue.bookId, "成功加入缓存队列", false));

            if (downloadNotificationManager == null) {
                downloadNotificationManager = new DownloadNotificationManager(getApplication());
            }
        }
        // 从队列顺序取出第一条下载
        if (downloadQueues.size() > 0 && !isBusy) {
            for (DownloadQueue downloadQueue : downloadQueues) {
                if (!downloadQueue.isCancel) {
                    downloadBook(downloadQueue);
                    isBusy = true;
                    break;
                }
            }

        }
    }

    public synchronized void downloadBook(final DownloadQueue downloadQueue) {
        AsyncTask<Integer, Integer, Integer> downloadTask = new AsyncTask<Integer, Integer, Integer>() {

            List<ChapterList.BookChapter> list = downloadQueue.list;
            String bookId = downloadQueue.bookId;
            int start = downloadQueue.start; // 起始章节
            int end = downloadQueue.end; // 结束章节

            @Override
            protected Integer doInBackground(Integer... params) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                int failureCount = 0;
                for (int i = start; i <= end && i <= list.size(); i++) {
                    if (canceled || downloadQueue.isCancel) {
                        break;
                    }
                    // 网络异常，取消下载
                    if (!NetworkUtils.isAvailable(XApplication.getInstance())) {
                        downloadQueue.isCancel = true;
                        post(new DownloadMessage(bookId, getString(R.string.book_read_download_error), true));
                        if (downloadNotificationManager != null) {
                            downloadNotificationManager.updateMessage(downloadQueue.title, getString(R.string.book_read_download_error));
                        }
                        failureCount = -1;
                        break;
                    }
                    if (!downloadQueue.isFinish && !downloadQueue.isCancel) {
                        // 章节文件不存在,则下载，否则跳过
                        if (CacheManager.getInstance().getChapterFile(bookId, i) == null) {
                            ChapterList.BookChapter chapters = list.get(i - 1);
                            String url = chapters.link;
                            int ret = download(url, bookId, chapters.title, i, list.size());
                            if (ret != 1) {
                                failureCount++;
                            }
                        } else {
                            post(new DownloadProgress(bookId, i, list.size(),
                                    true));
                            if (downloadNotificationManager != null) {
                                downloadNotificationManager.updateMessage(downloadQueue.title, String.format(
                                        getString(R.string.book_read_alreday_download), list.get(i - 1).title, i, list.size()));
                            }
                        }
                    }
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
                return failureCount;
            }


            @Override
            protected void onPostExecute(Integer failureCount) {
                super.onPostExecute(failureCount);
                if (downloadQueue.isCancel) {
                    // 释放 空闲状态
                    isBusy = false;
                    if (!canceled) {
                        // post一个空事件，通知继续执行下一个任务
                        post(new DownloadQueue());
                    } else {
                        downloadQueues.clear();
                    }
                    canceled = false;
                    return;
                }
                downloadQueue.isFinish = true;
                if (failureCount > -1) {
                    // 完成通知
                    post(new DownloadMessage(bookId,
                            String.format(getString(R.string.book_read_download_complete), failureCount), true));
                    if (downloadNotificationManager != null) {
                        downloadNotificationManager.updateMessage(downloadQueue.title, String.format(getString(R.string.book_read_download_complete), failureCount));
                    }
                }
                // 下载完成，从队列里移除
                downloadQueues.remove(downloadQueue);
                // 释放 空闲状态
                isBusy = false;
                if (!canceled) {
                    // post一个空事件，通知继续执行下一个任务
                    post(new DownloadQueue());
                } else {
                    downloadQueues.clear();
                }
                canceled = false;
                Timber.i(bookId + "缓存完成，失败" + failureCount + "章");
            }
        };
        downloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    private int download(String url, final String bookId, final String title, final int chapter, final int chapterSize) {

        final int[] result = {-1};

        Subscription subscription = bookApi.getChapterRead(url)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Chapter>() {
                    @Override
                    public void onNext(Chapter data) {
                        if (data.body != null) {
                            post(new DownloadProgress(bookId, chapter, chapterSize,
                                    true));
                            if (downloadNotificationManager != null) {
                                downloadNotificationManager.updateMessage(title, String.format(
                                        getString(R.string.book_read_download_progress), title, chapter, chapterSize));
                            }
                            CacheManager.getInstance().saveChapterFile(bookId, chapter, data);
                            result[0] = 1;
                        } else {
                            result[0] = 0;
                        }
                    }

                    @Override
                    public void onCompleted() {
                        result[0] = 1;
                    }

                    @Override
                    public void onError(Throwable e) {
                        result[0] = 0;
                    }
                });

        addSubscrebe(subscription);

        while (result[0] == -1) {
            try {
                Thread.sleep(350);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result[0];
    }

    public static void cancel() {
        canceled = true;
    }

    public void changeDownLoad(DownloadQueue downloadQueue) {
        if (!isBusy && !downloadQueue.isCancel) {
            post(new DownloadQueue());
        }
    }

    protected void unSubscribe() {
        if (mCompositeSubscription != null) {
            mCompositeSubscription.unsubscribe();
        }
    }

    protected void addSubscrebe(Subscription subscription) {
        if (mCompositeSubscription == null) {
            mCompositeSubscription = new CompositeSubscription();
        }
        mCompositeSubscription.add(subscription);
    }

    public static List<DownloadQueue> getDownloadQueues() {
        return downloadQueues;
    }
}
